package start.invoice;

import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

/**
 * 高精度数电票PDF生成器
 */
public class ElectronicInvoiceGenerator {
    // 常量定义 - 精确控制尺寸（使用iText的PageSize类适配）
    private static final PageSize PAGE_SIZE = PageSize.A4; // A4尺寸（595x841点）
    private static final float MARGIN_LEFT = 40f;
    private static final float MARGIN_RIGHT = 40f;
    private static final float MARGIN_TOP = 50f;
    private static final float MARGIN_BOTTOM = 50f;
    // 新增：通过PAGE_SIZE获取页面宽度，替代未定义的PAGE_WIDTH
    private static final float PAGE_WIDTH = PAGE_SIZE.getWidth();

    // 字体定义
    private PdfFont songFont;       // 宋体 - 正文
    private PdfFont songBoldFont;   // 宋体加粗 - 标题
    private PdfFont heiFont;        // 黑体 - 特殊标记

    // 颜色定义
    private static final Color BLACK = new DeviceRgb(0, 0, 0);
    private static final Color LIGHT_GRAY = new DeviceRgb(200, 200, 200);
    private static final Color DARK_GRAY = new DeviceRgb(100, 100, 100);

    public ElectronicInvoiceGenerator() throws IOException {
        // 初始化字体（兼容Windows系统字体）
        try {
            songFont = PdfFontFactory.createFont("C:/Windows/Fonts/simsun.ttc,0", PdfEncodings.IDENTITY_H);
            songBoldFont = PdfFontFactory.createFont("C:/Windows/Fonts/simsun.ttc,0", PdfEncodings.IDENTITY_H);
            //songBoldFont = PdfFontFactory.createFont("C:/Windows/Fonts/simsunb.ttc,0", PdfEncodings.IDENTITY_H);
            heiFont = PdfFontFactory.createFont("C:/Windows/Fonts/simhei.ttf", PdfEncodings.IDENTITY_H);
        } catch (IOException e) {
            // 修复：iText内置字体参数修正，去掉多余的编码参数
            songFont = PdfFontFactory.createFont("STSong-Light", PdfEncodings.IDENTITY_H);
            songBoldFont = songFont; // 内置字体无粗体时复用常规字体
            heiFont = songFont;
        }
    }

    /**
     * 生成数电票PDF
     */
    public void generate(ElectronicInvoice invoice, String outputPath) throws IOException {
        // 创建PDF文档
        PdfWriter writer = new PdfWriter(new File(outputPath));
        PdfDocument pdfDoc = new PdfDocument(writer);

        // 关键修正：通过PageSize设置页面尺寸，再传给Document
        Document document = new Document(pdfDoc, PAGE_SIZE);
        // 设置页边距
        document.setMargins(MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM, MARGIN_LEFT);

        // 1. 绘制发票标题区域
        drawTitleArea(document, invoice);

        // 2. 绘制发票头部信息（发票代码、号码等）
        drawHeaderInfo(document, invoice);

        // 3. 绘制买卖方信息区域
        drawBuyerSellerInfo(document, invoice);

        // 4. 绘制商品明细表格
        drawItemsTable(document, invoice.getItems());

        // 5. 绘制汇总信息区域
        drawSummaryArea(document, invoice);

        // 6. 绘制备注和附加信息
        drawRemarksArea(document, invoice);

        // 7. 绘制底部信息和签章区域
        drawFooterArea(document, invoice);

        document.close();
    }

    // 绘制发票标题（匹配示例中的“电子发票(增值税专用发票)”）
    // 绘制标题（红色+双下划线，匹配文档样式）
    // 绘制标题（红色+双下划线，适配iText 7 API）
    // 绘制标题（红色+双下划线，严格适配iText 7基础API）
    private void drawTitleArea(Document document, ElectronicInvoice invoice) {
        // 标题红色（匹配文档中"电子发票(增值税专用发票)"的红色样式）
        Color redColor = new DeviceRgb(220, 0, 0);

        // 主标题：红色文字，居中
        Paragraph title = new Paragraph("电子发票(增值税专用发票)")
                .setFont(songBoldFont)
                .setFontSize(16)
                .setTextAlignment(TextAlignment.CENTER)
                .setFontColor(redColor) // 标题文字设为红色
                .setMarginBottom(1f); // 缩小与下划线的间距
        document.add(title);

        // 双下划线实现（用带红色边框的空单元格模拟，兼容所有版本）
        // 第一条下划线
        Table underline1 = new Table(1);
        underline1.setWidth(document.getPdfDocument().getDefaultPageSize().getWidth() - 80); // 匹配标题宽度
        Cell line1 = new Cell().setHeight(1f).setBackgroundColor(redColor); // 红色线条
        underline1.addCell(line1);
        document.add(underline1);

        // 第二条下划线（与第一条间隔1f）
        document.add(new Paragraph("\n").setMargin(0)); // 控制间距
        Table underline2 = new Table(1);
        underline2.setWidth(document.getPdfDocument().getDefaultPageSize().getWidth() - 80);
        Cell line2 = new Cell().setHeight(1f).setBackgroundColor(redColor);
        underline2.addCell(line2);
        document.add(underline2);

        // 发票号码和开票日期（严格匹配文档内容）
        Paragraph invoiceNo = new Paragraph("发票号码: " + invoice.getInvoiceNumber()) // 对应文档中"发票号码:24372000000114349951"
                .setFont(songFont).setFontSize(10).setMarginTop(10f);
        Paragraph issueDate = new Paragraph("开票日期: " + invoice.getIssueDate()) // 对应文档中"开票日期:2024年07月04日"
                .setFont(songFont).setFontSize(10).setMarginBottom(15f);
        document.add(invoiceNo);
        document.add(issueDate);
    }

    /**
     * 绘制发票头部信息
     */
    private void drawHeaderInfo(Document document, ElectronicInvoice invoice) {
        // 构建头部信息表格（2行2列）
        // 修复：表格列宽计算修正，避免总宽度超过页面
        float headerTableWidth = PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT;
        float[] columnWidths = {headerTableWidth / 2, headerTableWidth / 2};
        Table headerTable = new Table(columnWidths);
        headerTable.setWidth(headerTableWidth);

        // 第一行：发票代码和发票号码
        Cell codeCell = new Cell().add(new Paragraph("发票代码: " + invoice.getInvoiceCode())
                .setFont(songFont).setFontSize(10));
        codeCell.setBorder(null);
        codeCell.setPadding(2f);

        Cell numberCell = new Cell().add(new Paragraph("发票号码: " + invoice.getInvoiceNumber())
                .setFont(songFont).setFontSize(10));
        numberCell.setBorder(null);
        numberCell.setPadding(2f);

        // 第二行：开票日期和校验码
        Cell dateCell = new Cell().add(new Paragraph("开票日期: " + invoice.getIssueDate())
                .setFont(songFont).setFontSize(10));
        dateCell.setBorder(null);
        dateCell.setPadding(2f);

        Cell checkCodeCell = new Cell().add(new Paragraph("校验码: " + invoice.getCheckCode())
                .setFont(songFont).setFontSize(10));
        checkCodeCell.setBorder(null);
        checkCodeCell.setPadding(2f);

        // 添加单元格到表格
        headerTable.addCell(codeCell);
        headerTable.addCell(numberCell);
        headerTable.addCell(dateCell);
        headerTable.addCell(checkCodeCell);

        document.add(headerTable);
        document.add(new Paragraph("\n"));
    }

    /**
     * 绘制买卖方信息区域
     */
    private void drawBuyerSellerInfo(Document document, ElectronicInvoice invoice) {
        // 买卖方信息表格（3行2列）
        // 直接在创建Table时指定列宽数组，无需后续设置
        float infoTableWidth = PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT;
        float columnWidth = (infoTableWidth - 10f) / 2;
        float[] columnWidths = {columnWidth, columnWidth};
        // 直接通过构造函数传入列宽数组和列间距
        Table infoTable = new Table(columnWidths);
        infoTable.setWidth(infoTableWidth);

        // 销售方信息标题
        Cell sellerTitleCell = new Cell().add(new Paragraph("销售方信息")
                .setFont(songBoldFont).setFontSize(11));
        sellerTitleCell.setBorder(null);
        sellerTitleCell.setBackgroundColor(LIGHT_GRAY);
        sellerTitleCell.setPadding(3f);

        // 购买方信息标题
        Cell buyerTitleCell = new Cell().add(new Paragraph("购买方信息")
                .setFont(songBoldFont).setFontSize(11));
        buyerTitleCell.setBorder(null);
        buyerTitleCell.setBackgroundColor(LIGHT_GRAY);
        buyerTitleCell.setPadding(3f);

        // 销售方详细信息
        Cell sellerInfoCell = new Cell().add(buildPartyInfoParagraph(invoice.getSeller()));
        sellerInfoCell.setBorder(null);
        sellerInfoCell.setPadding(5f);

        // 购买方详细信息
        Cell buyerInfoCell = new Cell().add(buildPartyInfoParagraph(invoice.getBuyer()));
        buyerInfoCell.setBorder(null);
        buyerInfoCell.setPadding(5f);

        // 空行（调整间距）
        Cell emptyCell = new Cell().setBorder(null);

        // 添加单元格到表格
        infoTable.addCell(sellerTitleCell);
        infoTable.addCell(buyerTitleCell);
        infoTable.addCell(sellerInfoCell);
        infoTable.addCell(buyerInfoCell);
        infoTable.addCell(emptyCell);
        infoTable.addCell(emptyCell);

        document.add(infoTable);
        document.add(new Paragraph("\n"));
    }

    /**
     * 构建单位信息段落
     */
    private Paragraph buildPartyInfoParagraph(PartyInfo party) {
        Paragraph p = new Paragraph();
        p.setFont(songFont).setFontSize(10);
        p.add("名称: " + party.getName() + "\n");
        p.add("纳税人识别号: " + party.getTaxpayerId() + "\n");
        p.add("地址、电话: " + party.getAddressPhone() + "\n");
        p.add("开户行及账号: " + party.getBankAccount());
        return p;
    }

    /**
     * 绘制商品明细表格
     */
    private void drawItemsTable(Document document, List<InvoiceItem> items) {
        // 商品明细表格列宽（精确匹配实际发票比例）
        float totalWidth = PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT;
        float[] columnWidths = {
                totalWidth * 0.25f,  // 货物或应税劳务、服务名称
                totalWidth * 0.12f,  // 规格型号
                totalWidth * 0.08f,  // 单位
                totalWidth * 0.10f,  // 数量
                totalWidth * 0.15f,  // 单价
                totalWidth * 0.15f,  // 金额
                totalWidth * 0.08f,  // 税率
                totalWidth * 0.10f   // 税额
        };

        Table itemsTable = new Table(columnWidths);
        itemsTable.setWidth(totalWidth);

        // 表格标题行
        String[] headers = {"货物或应税劳务、服务名称", "规格型号", "单位", "数量", "单价", "金额", "税率", "税额"};
        for (String header : headers) {
            Cell cell = new Cell().add(new Paragraph(header)
                    .setFont(songBoldFont).setFontSize(9));
            cell.setTextAlignment(TextAlignment.CENTER);
            cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
            cell.setBackgroundColor(LIGHT_GRAY);
            cell.setPadding(4f);
            itemsTable.addCell(cell);
        }

        // 表格内容行
        for (InvoiceItem item : items) {
            itemsTable.addCell(createItemCell(item.getName(), TextAlignment.LEFT));
            itemsTable.addCell(createItemCell(item.getModel(), TextAlignment.CENTER));
            itemsTable.addCell(createItemCell(item.getUnit(), TextAlignment.CENTER));
            itemsTable.addCell(createItemCell(item.getQuantity().toString(), TextAlignment.RIGHT));
            itemsTable.addCell(createItemCell(item.getUnitPrice().toString(), TextAlignment.RIGHT));
            itemsTable.addCell(createItemCell(item.getAmount().toString(), TextAlignment.RIGHT));
            itemsTable.addCell(createItemCell(item.getTaxRate(), TextAlignment.CENTER));
            itemsTable.addCell(createItemCell(item.getTaxAmount().toString(), TextAlignment.RIGHT));
        }

        document.add(itemsTable);
        document.add(new Paragraph("\n"));
    }

    /**
     * 创建商品明细单元格
     */
    private Cell createItemCell(String content, TextAlignment alignment) {
        Cell cell = new Cell().add(new Paragraph(content)
                .setFont(songFont).setFontSize(9));
        cell.setTextAlignment(alignment);
        cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
        cell.setPadding(3f);
        return cell;
    }

    /**
     * 绘制汇总信息区域
     */
    private void drawSummaryArea(Document document, ElectronicInvoice invoice) {
        // 汇总信息表格
        float totalWidth = PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT;
        float[] columnWidths = {totalWidth * 0.6f, totalWidth * 0.15f, totalWidth * 0.25f};
        Table summaryTable = new Table(columnWidths);

        // 修复：参数类型统一为String，避免类型不匹配
        addSummaryRow(summaryTable, "合计",
                invoice.getSubtotalAmount().toString(),
                invoice.getTotalTaxAmount().toString());
        addSummaryRow(summaryTable, "价税合计（大写）", "", invoice.getTotalAmountInWords());
        addSummaryRow(summaryTable, "价税合计（小写）", "", invoice.getTotalAmount());

        document.add(summaryTable);
        document.add(new Paragraph("\n"));
    }

    /**
     * 添加汇总行
     */
    private void addSummaryRow(Table table, String label, String leftValue, String rightValue) {
        Cell labelCell = new Cell().add(new Paragraph(label)
                .setFont(songBoldFont).setFontSize(10));
        labelCell.setBorder(null);
        labelCell.setPadding(4f);

        Cell leftCell = new Cell().add(new Paragraph(leftValue)
                .setFont(songFont).setFontSize(10));
        leftCell.setBorder(null);
        leftCell.setTextAlignment(TextAlignment.RIGHT);
        leftCell.setPadding(4f);

        Cell rightCell = new Cell().add(new Paragraph(rightValue)
                .setFont(songBoldFont).setFontSize(10));
        rightCell.setBorder(null);
        rightCell.setTextAlignment(TextAlignment.RIGHT);
        rightCell.setPadding(4f);

        table.addCell(labelCell);
        table.addCell(leftCell);
        table.addCell(rightCell);
    }

    /**
     * 绘制备注和附加信息
     */
    private void drawRemarksArea(Document document, ElectronicInvoice invoice) {
        // 备注表格
        float totalWidth = PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT;
        Table remarksTable = new Table(new float[]{totalWidth});

        // 备注标题
        Cell titleCell = new Cell().add(new Paragraph("备注")
                .setFont(songBoldFont).setFontSize(10));
        titleCell.setBackgroundColor(LIGHT_GRAY);
        titleCell.setPadding(3f);
        remarksTable.addCell(titleCell);

        // 备注内容
        Cell contentCell = new Cell().add(new Paragraph(invoice.getRemarks())
                .setFont(songFont).setFontSize(10));
        contentCell.setPadding(5f);
        remarksTable.addCell(contentCell);

        document.add(remarksTable);
        document.add(new Paragraph("\n"));
    }

    /**
     * 绘制底部信息和签章区域
     */
    private void drawFooterArea(Document document, ElectronicInvoice invoice) {
        // 底部信息表格
        float totalWidth = PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT;
        Table footerTable = new Table(new float[]{totalWidth / 3, totalWidth / 3, totalWidth / 3});
        footerTable.setWidth(totalWidth);

        // 开票人、复核人、收款人
        Cell issuerCell = new Cell().add(new Paragraph("开票人: " + invoice.getIssuer())
                .setFont(songFont).setFontSize(10));
        issuerCell.setBorder(null);
        issuerCell.setTextAlignment(TextAlignment.CENTER);

        Cell reviewerCell = new Cell().add(new Paragraph("复核人: " + invoice.getReviewer())
                .setFont(songFont).setFontSize(10));
        reviewerCell.setBorder(null);
        reviewerCell.setTextAlignment(TextAlignment.CENTER);

        Cell receiverCell = new Cell().add(new Paragraph("收款人: " + invoice.getReceiver())
                .setFont(songFont).setFontSize(10));
        receiverCell.setBorder(null);
        receiverCell.setTextAlignment(TextAlignment.CENTER);

        footerTable.addCell(issuerCell);
        footerTable.addCell(reviewerCell);
        footerTable.addCell(receiverCell);

        document.add(footerTable);

        // 电子签章区域（绘制矩形框示意）
        PdfPage page = document.getPdfDocument().getLastPage();
        PdfCanvas canvas = new PdfCanvas(page);
        Rectangle rect = new Rectangle(
                MARGIN_LEFT + totalWidth - 150,
                MARGIN_BOTTOM + 30,
                120,
                60
        );
        canvas.rectangle(rect);
        canvas.stroke();

        // 修复：Canvas构造方法参数修正，添加字体设置
        //Canvas signatureCanvas = new Canvas(canvas, document.getPdfDocument(), rect);
        Canvas signatureCanvas = new Canvas(canvas, rect);
        signatureCanvas.setFont(songFont);
        signatureCanvas.add(new Paragraph("电子签章")
                .setFontSize(12)
                .setTextAlignment(TextAlignment.CENTER));
        signatureCanvas.close(); // 关闭Canvas释放资源
    }
}